import { io } from "socket.io-client";
import { uuidv4 } from "./uuid"
import { TIMEOUTS } from './constant'
/**
 * 连接到electron主线程的bridge-server
 * 通信方式  electron-render <——> electron-main  <——> bridge-server <——> bridge-client <——> chrome-extension 
 */
class BridgeClient {

    nativeHost = null;
    socket = null
    pendingRequests = new Map();

    setNativeHost(nativeHost) {
        this.nativeHost = nativeHost;
    }

    constructor() {
        this.setupConnection();
    }

    setupConnection() {
        try {

            this.socket = io('ws://localhost:9988', {
                reconnection: true,
                transports: ['polling', 'websocket']
            });

            this.socket.on("connect", () => {

            });

            // 断开连接
            this.socket.on("disconnect", () => {
                this.cleanup()
            });

            // 连接失败
            this.socket.on("connect_error", (error) => {
                this.cleanup()
                if (this.socket.active) {
                    // 这里加上console.log会导致浏览器拓展连接失败 why?
                    // temporary failure, the socket will automatically try to reconnect
                } else {
                    // the connection was denied by the server
                    // in that case, `socket.connect()` must be manually called in order to reconnect
                }
            });

            // 收到socket消息
            this.socket.on('bridge:message', async (message: { type: string; requestId?: string; responseId?: string; error?: string; payload: any }) => {

                if (!message || typeof message !== 'object') {
                    this.sendMessage({
                        error: 'Invalid message format'
                    });
                    return;
                }

                if (message?.responseId) {
                    const requestId = message.responseId;
                    const pending = this.pendingRequests.get(requestId);

                    if (pending) {
                        clearTimeout(pending.timeoutId);
                        if (message.error) {
                            pending.resolve({
                                error: message.error
                            });
                        } else {
                            pending.resolve(message.payload);
                        }
                        this.pendingRequests.delete(requestId);
                    }
                    return;
                }

                if (message.payload?.type === 'ping_from_server') {
                    // 收到ping,返回pong
                    this.sendMessage({
                        responseId: message.requestId,
                        payload: {
                            type: 'pong_to_server'
                        }
                    })
                    return;
                }

                if (message.type === 'native') {
                    if (message.requestId) {
                        try {
                            const response = await this.nativeHost?.invokeMessage(message.payload);
                            this.sendMessage({
                                responseId: message.requestId,
                                payload: response
                            })
                        } catch (error) {
                            this.sendMessage({
                                responseId: message.requestId,
                                error: '与浏览器插件通信异常',
                            })
                        }
                    } else {
                        this.nativeHost?.sendMessage(message.payload)
                    }
                    return
                }

                // 有requestId，需要响应
                if (message?.requestId) {
                    this.sendMessage({
                        responseId: message.requestId,
                        payload: {
                            message: 'client执行成功'
                        }
                    })
                }
            });
        } catch (error) {

        }
    }

    // 向socket server发送消息，并等待response
    invokeMessage(payload, timeoutMs = TIMEOUTS.DEFAULT_REQUEST_TIMEOUT) {
        return new Promise((resolve, reject) => {

            if (!this.socket) {
                resolve({
                    error: 'socket client未建立连接'
                })
            }

            const requestId = uuidv4();

            const timeoutId = setTimeout(() => {
                this.pendingRequests.delete(requestId); // Remove from Map after timeout
                resolve({
                    error: `Request timed out after ${timeoutMs}ms`
                });
            }, timeoutMs);

            // Store request's resolve/reject functions and timeout ID
            this.pendingRequests.set(requestId, { resolve, reject, timeoutId });

            // 给bridgeServer发送消息
            this.sendMessage({
                requestId,
                payload
            })
        });
    }

    // 向socket server发送消息，无需等待response
    sendMessage(message) {
        if (!message || typeof message !== 'object') {
            throw Error('Invalid message format')
        }
        this.socket?.emit('bridge:message', message)
    }

    cleanup() {
        // Reject all pending requests
        this.pendingRequests.forEach((pending) => {
            clearTimeout(pending.timeoutId);
            pending.reject(new Error('Native host is shutting down or Chrome disconnected.'));
        });
        this.pendingRequests.clear();
        process.exit(0);
    }

}

const bridgeClient = new BridgeClient();

setInterval(() => {
    bridgeClient.invokeMessage({ type: 'ping_from_client' })
}, 5000)

export { bridgeClient };